function isDef (v) {
  return v !== undefined && v !== null
}

const getFirstComponentChild = (children) => {
  if (Array.isArray(children)) {
    for (let i = 0; i < children.length; i++) {
      const c = children[i]
      if ((isDef(c) && isDef(c.componentOptions)) || (c.isComment && c.asyncFactory)) {
        return c
      }
    }
  }
}

export default {
  abstract: true,
  name: 'keep-alive-janlay',
  created () {
    this.cache = Object.create(null)
    this.keys = []
  },
  render () {
    const slot = this.$slots.default
    const vnode = getFirstComponentChild(slot)
    const componentOptions = vnode && vnode.componentOptions
    if (componentOptions) {
      const { cache } = this
      let keys = this.keys
      // 相同的构造器（constructor）可能会注册为不同的本地组件，所以仅有一个 cid 是不够的（#3269）
      const key = vnode.key || componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')

      if (cache[key]) {
        vnode.componentInstance = cache[key].componentInstance
        keys = keys.filter(k => k !== key)
        keys.push(key)
      } else {
        cache[key] = vnode
        keys.push(key)
      }
      vnode.data.keepAlive = true
    }

    return vnode || slot
  }
}
